package com.iwhalecloud.bss.kite.cucc.service.rule.check.util;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.iwhalecloud.bss.kite.client.enums.RuleEventType;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteMapUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.rule.enums.CuccRuleEventType;
import com.iwhalecloud.bss.kite.cucc.client.dto.batch.KiteBatchAcceptDetail;
import com.iwhalecloud.bss.kite.cucc.client.dto.offer.CategoryOfferDTO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.dataservice.cache.CategoryOfferCache;
import com.iwhalecloud.bss.kite.cucc.dataservice.mapper.batch.KiteBatchAcceptDetailMapper;
import com.iwhalecloud.bss.kite.cucc.service.batch.BatchAcceptUtil;
import com.iwhalecloud.bss.kite.dataservice.cache.*;
import com.iwhalecloud.bss.kite.dataservice.entity.DcPublic;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.OfferRelInfo;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.ProdAttr;
import com.iwhalecloud.bss.kite.dataservice.util.GeneralSwitchUtils;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.inst.*;
import com.iwhalecloud.bss.kite.manager.inst.change.KiteInstChange;
import com.iwhalecloud.bss.kite.service.rule.RuleInitUtil;
import com.iwhalecloud.bss.kite.service.rule.RuleTrigger;
import com.iwhalecloud.bss.kite.service.rule.RuleUtil;
import com.ztesoft.bss.base.staticdata.CoreDataOffer;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.bss.rul.core.client.dto.common.RuleCommonParam;
import com.ztesoft.bss.rul.core.client.dto.instspec.InstSpecRel;
import com.ztesoft.bss.rul.core.client.dto.kite.KiteRuleRequest;
import com.ztesoft.bss.rul.core.client.dto.kite.KiteRuleResponse;
import com.ztesoft.bss.rul.core.client.dto.prod.ProdInst;
import com.ztesoft.bss.rul.core.client.dto.rule.InputObject;
import com.ztesoft.bss.rul.local.dataplug.valid.shopcart.dto.CartGroupInstReq;

import java.util.*;
import java.util.stream.Collectors;

/**
 *  产品包规则触发调用
 *  chenkaiwen
 */
public class CuccRuleTrigger {

    /**
     * 付费关系删除时机规则校验-ET_PROD_INST_ACCT_REL_ADD
     * @param sceneInstId
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse onDelOfferInstAcctCheck(String sceneInstId , RuleCommonParam ruleCommonParam, KiteOfferInstAcct kiteOfferInstAcct){
        KiteRuleRequest ruleRequest = RuleInitUtil
                .newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_PROD_INST_ACCT_REL_DEL.name());
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        CuccRuleTrigger.setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        //删除付费关系
        Map offerInstAcctMap = KiteMapUtils.beanToMap(kiteOfferInstAcct);
        offerInstAcctMap.put("actionType", KeyConsts.ACTION_TYPE_D);
        List<Map> offerInstAcctMapList = new ArrayList<Map>();
        offerInstAcctMapList.add(offerInstAcctMap);
        ruleCommonParam.getParams().put("prodInstAcctRels", offerInstAcctMapList);

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        /**二次类业务服务提供编码*/
        List<String> busiChangeServiceOfferId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");
        if(KiteListUtils.isEmpty(busiChangeServiceOfferId)){
            busiChangeServiceOfferId = Collections.EMPTY_LIST;
        }
        ruleCommonParam.getParams().put("busiChangeServiceOfferId", busiChangeServiceOfferId);


        /**
         * 销售品instSpecRel
         */
        List<InstSpecRel> offerInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        List<InstSpecRel> instSpecRelList = new ArrayList<>();
        instSpecRelList.addAll(offerInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRelList, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRelList));
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        return RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
    }


    /**
     * 增加资费规则校验-ET_ADDTIONAL_OFFER_INST_ADD
     * @param scenInstId
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse onAddAdditionalOfferInstCheck(String scenInstId, RuleCommonParam ruleCommonParam,List offerInstFeeLis){
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(scenInstId, ruleCommonParam,CuccRuleEventType.ET_ADDTIONAL_OFFER_INST_FEE_ADD.name());
        String serviceOfferId = getServiceOfferId(scenInstId);
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        RuleTrigger.setSceneInstCommonCheckInfo(scenInstId, ruleCommonParam);
        //当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }
        //新增资费
         List<Map> oferInstFeeMapList = new ArrayList<>();
        offerInstFeeLis.stream().forEach(kiteOfferInst -> {
            Map item = KiteMapUtils.beanToMap(kiteOfferInst);
            oferInstFeeMapList.add(item);
        });
        ruleCommonParam.getParams().put("offerInstFee", oferInstFeeMapList);


        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(scenInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        /**二次类业务服务提供编码*/
        List<String> busiChangeServiceOfferId = RuleUtil.getQuerySceneInstService().getExtParameterValue(scenInstId, "BUSI_CHANGE_SERVICEOFFERID");
        if(KiteListUtils.isEmpty(busiChangeServiceOfferId)){
            busiChangeServiceOfferId = Collections.EMPTY_LIST;
        }
        ruleCommonParam.getParams().put("busiChangeServiceOfferId", busiChangeServiceOfferId);



        //资费instSpecRel
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(scenInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, scenInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(scenInstId, ruleCommonParam.getCustId());
        KiteRuleResponse response = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return response;
    }


    /**
     *  设备体验包业务变更-平台属性校验
     * @param sceneInstId
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse checkPlatformType(String sceneInstId , RuleCommonParam ruleCommonParam){
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, CuccRuleEventType.ET_MENU_CLICK.name());
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        /**二次类业务服务提供编码*/
        List<String> busiChangeServiceOfferId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");
        if(KiteListUtils.isEmpty(busiChangeServiceOfferId)){
            busiChangeServiceOfferId = Collections.EMPTY_LIST;
        }
        ruleCommonParam.getParams().put("busiChangeServiceOfferId", busiChangeServiceOfferId);


        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        return RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
    }

    /**
     * 加急延期时间校验
     * @param sceneInstId
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse checkUrgentOrDelay(String sceneInstId , RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, CuccRuleEventType.ET_URGENT_OR_DELAY_COMMIT.name());
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        /**二次类业务服务提供编码*/
        List<String> busiChangeServiceOfferId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");
        if(KiteListUtils.isEmpty(busiChangeServiceOfferId)){
            busiChangeServiceOfferId = Collections.EMPTY_LIST;
        }
        ruleCommonParam.getParams().put("busiChangeServiceOfferId", busiChangeServiceOfferId);


        KiteSceneInst kiteSceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        return RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
    }

    /**销售品新增规则校验*/
    public static KiteRuleResponse onAddOfferInstCheck(String sceneInstId,RuleCommonParam ruleCommonParam){
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, CuccRuleEventType.ET_OFFER_INST_ADD.name());
        String serviceOfferId = getServiceOfferId(sceneInstId);
        CuccRuleTrigger.setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }


        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }


    /**
     * 设置场景校验信息setSceneInstCommonCheckInfo
     * @param sceneInstId
     * @param ruleCommonParam
     */
    public static void setSceneInstCommonCheckInfo(String sceneInstId,RuleCommonParam ruleCommonParam){
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        Map pramMap = ruleCommonParam.getParams();
        if(Objects.isNull(pramMap)){
            ruleCommonParam.setParams(new HashMap<>());
        }
        if(Objects.isNull(sceneInst)){
            return ;
        }
        List<String> skuList = new ArrayList<>();
        String rootInstId = sceneInst.getRootInstId();
        KiteOfferInst rootOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(sceneInst.getCustId(), rootInstId);
        Map<String, KiteAttr> map = rootOfferInst.getAttrMap();
        String cateId = "";
        if (KiteMapUtils.isNotEmpty(map)){
            KiteAttr attr = map.get("cateId");
            if (Objects.nonNull(attr)){
                cateId = attr.getValue();
            }
        }
        ruleCommonParam.getParams().put("cateId", cateId);
        skuList.add(rootOfferInst.getOfferId());
        String acceptSpu = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "ACCEPT_GOODS_SPU");
        if(!skuList.contains(acceptSpu)){
            skuList.add(acceptSpu);
        }

        List<KiteOfferInst> offerInstList = RuleUtil.getQuerySceneInstService().listMainOfferInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(offerInstList)){
            offerInstList.stream().forEach(offerInst -> {
                if(!skuList.contains(offerInst.getOfferId())){
                    skuList.add(offerInst.getOfferId());
                }
            });
        }

        if(!skuList.contains(rootOfferInst.getOfferId())){
            skuList.add(rootOfferInst.getOfferId());
        }
        ruleCommonParam.getParams().put("goodSku", skuList);

        // 场景编码
        String tackCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tackCode);
        // 规则入參添加环节编码
        String taskCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "taskCode", "OrderInput");
        ruleCommonParam.getParams().put("taskCode", taskCode);
        // 原单业务动作
        String bizType = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "bizType");
        ruleCommonParam.getParams().put("bizType", bizType);

        /** 二次类业务服务提供编码 */
        List<String> busiChangeServiceOfferId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "BUSI_CHANGE_SERVICEOFFERID");
        ruleCommonParam.getParams().put("busiChangeServiceOfferId", busiChangeServiceOfferId);
    }


    /**获取服务提供Id*/
    public static String getServiceOfferId(String sceneInstId){
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        String serviceOfferId = sceneInst.getServiceOfferId();

        //追加订购
        String addOrder = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, LocalKeyConsts.ADD_ORDE);
        if(KiteStringUtils.equals(addOrder, "T")){
            serviceOfferId = "2019";
        }
        return serviceOfferId;
    }


    /**安全产品产品实例删除校验*/
    public static KiteRuleResponse SafeProductOnDelProdInstCheck(String sceneInstId, RuleCommonParam ruleCommonParam){
        RuleTrigger.setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_PRODUCT_DEL.name());

        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }

    /**收入归集集团删除校验*/
    public static KiteRuleResponse memberDelCheck(String sceneInstId, RuleCommonParam ruleCommonParam){
        RuleTrigger.setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        RuleTrigger.setRuleOtherInfo(ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_PROD_INST_FUNCS_DEL.name());

        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }

    /**
     * 【专线】商品超时起租校验
     * @param sceneInstId
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse specialLineStartRentCheck(String sceneInstId, RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(sceneInstId, ruleCommonParam, CuccRuleEventType.ET_SPECIALLINE_STARTRENT_CHECK.name());
        setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);

        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }

        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);
        // 获取订单编码
        String orderId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "orderId");
        ruleCommonParam.getParams().put("orderId", orderId);

        //属性值校验
        Map<String,Object> checkAttrValueMap = new HashMap<>();
        //取公共属性
        List<KiteAttr> checkCommonAttrList = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId).stream().filter(kiteAttr ->
            KiteStringUtils.equalsAny(kiteAttr.getFieldName(), LocalKeyConsts.START_RENT_TIME, LocalKeyConsts.START_RENT_TIMEOUT_REASON,LocalKeyConsts.START_RENT_TIMEOUT_ATTACHMENT,
                LocalKeyConsts.START_RENT_TIMEOUT_DESC, LocalKeyConsts.BUSINESS_NUMBER)).collect(Collectors.toList());
        checkCommonAttrList.stream().forEach(kiteAttr -> {
            checkAttrValueMap.put(kiteAttr.getFieldName(), kiteAttr);
        });
        ruleCommonParam.getParams().put("checkAttrValueMap", checkAttrValueMap);

        // ruleInstSpec
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }

    /**
     * 【趸交】订单缴费规则校验
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse singlePaymentFeePayChargeCheck(RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(ruleCommonParam, CuccRuleEventType.ET_FEE_PAY_CHARGE_CHECK.name());
        setRuleOtherInfo(ruleCommonParam);

        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }
        InputObject busiObject = new InputObject();
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }


    /**
     * 【趸交】订单终止校验规则
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse singlePaymentFeeTerminationCheck(String sceneInstId, RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(sceneInstId, ruleCommonParam,CuccRuleEventType.ET_ADDTIONAL_OFFER_INST_FEE_ADD.name());
        setRuleOtherInfo(ruleCommonParam);
        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }

        String serviceOfferId = getServiceOfferId(sceneInstId);

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        //资费instSpecRel
        List<InstSpecRel> instSpecRels = new ArrayList<>();
        List<InstSpecRel> offerInstInstSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(offerInstInstSpecRels);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        KiteRuleResponse response = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);

        return response;
    }


    public static KiteRuleResponse checkOrderPreViewCommon(String sceneInstId,String custId,RuleCommonParam ruleCommonParam){
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_ORDER_PREVIEW_COMMON.name());
        setRuleOtherInfo(ruleCommonParam);
        setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }
        long time1 = System.currentTimeMillis();
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        String cateId = "";
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        String rootInstId = sceneInst.getRootInstId();
        KiteOfferInst rootOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(custId, rootInstId);
        String rootOfferId = rootOfferInst.getOfferId();
        //200000106
        Map<String, KiteAttr> map = rootOfferInst.getAttrMap();
        if (KiteMapUtils.isNotEmpty(map)){
            KiteAttr attr = map.get("cateId");
            if (Objects.nonNull(attr)){
                cateId = attr.getValue();
            }
        }

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);

        //临时处理，融合成员起租时不调规则
        String codea = DcPublicCache.getCodea("202103100001", "RongHeGoodsCateIds");
        String tacheCodes = DcPublicCache.getCodea("202103100001", "RongHeTacheCodes");
        if (!KiteStringUtils.isEmpty(codea) && Arrays.asList(codea.split(",")).contains(cateId)
            && !KiteStringUtils.isEmpty(tacheCodes) && Arrays.asList(tacheCodes.split(",")).contains(tacheCode)) {
            return null;
        }

        //收入归集成员退出   成员信息
        if(KiteStringUtils.equals(serviceOfferId,"2022")){
            List<Map<String,Object>> delMemList = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "delGroupUserInfos");
            ruleCommonParam.getParams().put("delMemList", Objects.isNull(delMemList)?new ArrayList<>():delMemList);
        }

        //账户关系
        List acctRelList = new ArrayList();
        if(Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstAcct> offerInstAccts = RuleUtil.getQuerySceneInstService().listOfferInstAccts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstAccts)){
                offerInstAccts.stream().forEach(offerInstAcct ->{
                    Map acctRelMap = KiteMapUtils.beanToMap(offerInstAcct);
                    acctRelList.add(acctRelMap);
                });
            }
        }
        ruleCommonParam.getParams().put("prodInstAcctRels", acctRelList);


        //折扣审批信息
        List kiteOfferInstDiscountList = Lists.newArrayList();
        if (Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstDiscount> offerInstDiscounts = RuleUtil.getQuerySceneInstService().listOfferInstDiscounts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstDiscounts)){
                offerInstDiscounts.stream().forEach(offerInstDiscount ->{
                    Map offerInstDiscountMap = KiteMapUtils.beanToMap(offerInstDiscount);
                    kiteOfferInstDiscountList.add(offerInstDiscountMap);
                });
            }
        }
        ruleCommonParam.getParams().put("offerInstDiscount", kiteOfferInstDiscountList);

        /***
         * 公共信息
         */
        List<KiteAttr> kiteAttrs = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId);
        List attrMapList = new ArrayList();
        kiteAttrs.stream().forEach(commAttr ->{
            attrMapList.add(KiteMapUtils.beanToMap(commAttr));
        });

        ruleCommonParam.getParams().put("commonAttrs", attrMapList);

        /**
         * 资费信息
         */
        List offerInstFeeList = getOfferInstFee(sceneInstId);
        ruleCommonParam.getParams().put("offerInstFee", offerInstFeeList);
        ruleCommonParam.getParams().put("offerFeeSpecMap", getCategoryInfoByInsts(sceneInstId, offerInstFeeList));



        //属性值校验
        Map<String,Object> checkAttrValueMap = new HashMap<>();
        //取产品属性值
        List<KiteProdInst> prodInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(prodInstList)){
            KiteProdInst prodInst = prodInstList.get(0);
            Map<String,KiteAttr> prodInstAttrMap = prodInst.getAttrMap();
            Set<String> keySet = prodInstAttrMap.keySet();
            keySet.stream().forEach(key ->{
                if(KiteStringUtils.equalsAny(key,"2_0000122","2_0000123","2_0000209","2_0000105","2_0000209","2_0000105","2_0000004","2_0000212","2_0000211",LocalKeyConsts.BUSINESS_NUMBER,"2_0000117")){
                    checkAttrValueMap.put(key, prodInstAttrMap.get(key));
                }
            });
        }
        //取公共属性
        List<KiteAttr> checkCommonAttrList = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId).stream().filter(kiteAttr ->
            KiteStringUtils.equalsAny(kiteAttr.getFieldName(),"ORD10012","2_0000004","2_0000212",LocalKeyConsts.BUSINESS_NUMBER)).collect(Collectors.toList());
        checkCommonAttrList.stream().forEach(kiteAttr -> {
            checkAttrValueMap.put(kiteAttr.getFieldName(), kiteAttr);
        });
        ruleCommonParam.getParams().put("checkAttrValueMap", checkAttrValueMap);


        //产品InstSpecRel
        List<InstSpecRel> prodInstSpecRelList = new ArrayList<InstSpecRel>();
        List<KiteProdInst> kiteProdInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(kiteProdInstList)){
            for(KiteProdInst prodInst : kiteProdInstList){
                List<InstSpecRel> prodInstSpecRels = RuleUtil.getInstSpecRelByInst(prodInst, serviceOfferId,custId,sceneInstId);
                prodInstSpecRelList.addAll(prodInstSpecRels);
            }
        }
        //销售品InstSpecRel
        List<InstSpecRel> instSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(prodInstSpecRelList);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        long time2 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOrderPreViewCommon preparedata ===============" + (time2 - time1));

        CartGroupInstReq cartGroupInstReq = CuccRuleUtil.transGroupCardInstToReq(ruleRequest, busiObject);
        ruleCommonParam.getParams().put("cartGroupInstReq", cartGroupInstReq);
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);

        long time3 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOrderPreViewCommon runRule ===============" + (time3 - time2));
        return ruleResponse;
    }

    public static void setRuleOtherInfo(RuleCommonParam commonParam){
        String staffCode = ContextUtil.getSimpleLoginInfo().getStaffCode();
        String postLanId = ContextUtil.getLoginInfo().getUserInfo().getPostLanId();
        String postProvinceNbr = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        String orgLevel = ContextUtil.getLoginInfo().getOrgInfo().getOrgLevel() + "";
        Map<String,String> staffInfo = new HashMap<String,String>();
        staffInfo.put("staffCode", staffCode);
        staffInfo.put("postLanId", postLanId);
        staffInfo.put("postProvinceNbr", postProvinceNbr);
        staffInfo.put("orgLevel", orgLevel);
        Map<String,Object> commParamMap = commonParam.getParams();
        if(!Objects.nonNull(commParamMap)){
            commParamMap = new HashMap<String,Object>();
        }
        commParamMap.put("staffInfo", staffInfo);
        commParamMap.put("areaLanId",ContextUtil.getLandId());
        commonParam.setParams(commParamMap);
    }

    public static List getOfferInstFee(String sceneInstId){
        List<KiteOfferInst> offerInstList = new ArrayList<>();
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        offerInstList.addAll(RuleUtil.getQuerySceneInstService().listMainOfferInsts(sceneInstId));
        offerInstList.addAll(RuleUtil.getQuerySceneInstService().listPromotionOfferInsts(sceneInstId));
        List offerInstFeeList = new ArrayList();

        for(KiteOfferInst kiteofferInst: offerInstList){
            List<KiteOfferInst> offerInstFees = RuleUtil.getQuerySceneInstService().listAdditionalOfferInstsFromMainOfferInst(sceneInst.getCustId(), kiteofferInst.getOfferInstId());

            if(KiteStringUtils.isEqual(kiteofferInst.getActionType().name(), ActionType.D.name())) {
                // 天津互联网附加商品删除，资费不支持再次订购当月，仅可以从次月开始订购的商品配置
                List<DcPublic> dcPublics = DcPublicCache.get("220113001");
                boolean flag = dcPublics.stream().anyMatch(dcPublic -> KiteStringUtils.isEqual(dcPublic.getPcode(), kiteofferInst.getOfferId()));
                if(flag) {
                    List<KiteInstChange> instChangeList = RuleUtil.getQuerySceneInstService().listInstChanges(sceneInstId, InstType.ADDITIONAL_OFFER_INST);
                    for (KiteInstChange instChange : instChangeList) {
                        List<OfferRelInfo> offerRelInfoList = OfferCache.get(kiteofferInst.getOfferId()).listAllOfferRels().stream().filter(offerRelInfo -> {
                            return CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType()) && KiteStringUtils.equalsAny(offerRelInfo.getRelType(), CoreDataOffer.OFF_0006_100000, CoreDataOffer.OFF_0006_120000);
                        }).collect(Collectors.toList());
                        KiteOfferInst additionOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(sceneInst.getCustId(), instChange.getSubInstId());
                        // 对于前置环节中新增的资费,场景还原时没有设置变动实例,所以当前场景删除时资费实例动作不会更新为X,这里通过结合originalActionType判断
                        if (Objects.nonNull(additionOfferInst) && KiteStringUtils.isEqual(additionOfferInst.getActionType().name(), ActionType.D.name()) && !KiteStringUtils.isEqual(instChange.getOldValue(), ActionType.A.name())) {
                            List<OfferRelInfo> filter = offerRelInfoList.stream().filter(offerRelInfo -> KiteStringUtils.isEqual(offerRelInfo.getzOfferId(), additionOfferInst.getOfferId())).collect(Collectors.toList());
                            if (KiteListUtils.isNotEmpty(filter)) {
                                offerInstFees.add(additionOfferInst);
                            }
                        }
                    }
                }
            }

            if(KiteListUtils.isNotEmpty(offerInstFees)){
                offerInstFees.stream().forEach(offerInstfee -> {
                    Map offerInstFee = KiteMapUtils.beanToMap(offerInstfee);
                    Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(offerInstfee.getOfferId()))
                        .map(Offer::getOfferMap).orElse(new HashMap<>());
                    String discntCode = KiteMapUtils.getStrValue(offerMap, "discntCode");
                    String payType = KiteMapUtils.getStrValue(offerMap, "payType");
                    offerInstFee.put("discntCode", discntCode);
                    offerInstFee.put("payType", payType);
                    offerInstFeeList.add(offerInstFee);
                });
            }
        }
        return offerInstFeeList;
    }

    /**
     * 点击订单预览时校验合同和收货信息
     * @return
     */
    public static KiteRuleResponse  checkOnOrderPreview(String sceneInstId,String custId,RuleCommonParam ruleCommonParam){
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_ORDER_PREVIEW.name());
        setRuleOtherInfo(ruleCommonParam);
        setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }
        long time1 = System.currentTimeMillis();
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        String cateId = "";
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        String rootInstId = sceneInst.getRootInstId();
        KiteOfferInst rootOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(custId, rootInstId);

        Map<String, KiteAttr> map = rootOfferInst.getAttrMap();
        if (KiteMapUtils.isNotEmpty(map)){
            KiteAttr attr = map.get("cateId");
            if (Objects.nonNull(attr)){
                cateId = attr.getValue();
            }
        }
        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);
        //临时处理，融合成员起租时不调规则
        String codea = DcPublicCache.getCodea("202103100001", "RongHeGoodsCateIds");
        String tacheCodes = DcPublicCache.getCodea("202103100001", "RongHeTacheCodes");
        if (!KiteStringUtils.isEmpty(codea) && Arrays.asList(codea.split(",")).contains(cateId)
            && !KiteStringUtils.isEmpty(tacheCodes) && Arrays.asList(tacheCodes.split(",")).contains(tacheCode)) {
            return null;
        }

        /** 总部直签打标处理 */
        String isCenterDirectMark = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "isCenterDirectMark");
        if (KiteStringUtils.isNotEmpty(isCenterDirectMark)) {
            ruleCommonParam.getParams().put("isCenterDirectMark", isCenterDirectMark);
        }

        //账户关系
        List acctRelList = new ArrayList();
        if(Objects.nonNull(rootOfferInst)){
            String accCateId = Optional.ofNullable(rootOfferInst.getAttr("cateId")).map(KiteAttr::getDefaultValue).orElse("");
            if(!isAddRoleProduct(accCateId)){
                List<KiteOfferInstAcct> offerInstAccts = RuleUtil.getQuerySceneInstService().listOfferInstAccts(custId, rootOfferInst.getOfferInstId());
                if (KiteListUtils.isNotEmpty(offerInstAccts)){
                    offerInstAccts.stream().forEach(offerInstAcct ->{
                        Map acctRelMap = KiteMapUtils.beanToMap(offerInstAcct);
                        acctRelList.add(acctRelMap);
                    });
                }
            }
        }
        ruleCommonParam.getParams().put("prodInstAcctRels", acctRelList);


        //折扣审批信息
        List kiteOfferInstDiscountList = Lists.newArrayList();
        if(Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstDiscount> offerInstDiscounts = RuleUtil.getQuerySceneInstService().listOfferInstDiscounts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstDiscounts)){
                offerInstDiscounts.stream().forEach(offerInstDiscount ->{
                    Map offerInstDiscountMap = KiteMapUtils.beanToMap(offerInstDiscount);
                    kiteOfferInstDiscountList.add(offerInstDiscountMap);
                });
            }
        }
        ruleCommonParam.getParams().put("offerInstDiscount", kiteOfferInstDiscountList);

        /**
         * 公共属性
         */
        List<KiteAttr> kiteAttrs = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId);
        List attrMapList = new ArrayList();
        kiteAttrs.stream().forEach(commAttr ->{
            attrMapList.add(KiteMapUtils.beanToMap(commAttr));
        });
        ruleCommonParam.getParams().put("commonAttrs", attrMapList);


        /**
         * 资费信息
         */
        List offerInstFeeList = getOfferInstFee(sceneInstId);
        ruleCommonParam.getParams().put("offerInstFee", offerInstFeeList);
        ruleCommonParam.getParams().put("offerFeeSpecMap", getCategoryInfoByInsts(sceneInstId, offerInstFeeList));



        //产品InstSpecRel
        List<InstSpecRel> prodInstSpecRelList = new ArrayList<InstSpecRel>();
        List<KiteProdInst> kiteProdInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(kiteProdInstList)){
            for(KiteProdInst prodInst : kiteProdInstList){
                List<InstSpecRel> prodInstSpecRels = RuleUtil.getInstSpecRelByInst(prodInst, serviceOfferId,custId,sceneInstId);
                prodInstSpecRelList.addAll(prodInstSpecRels);
            }
        }
        //销售品InstSpecRel
        List<InstSpecRel> instSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(prodInstSpecRelList);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        long time2 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOnOrderPreview preparedata ===============" + (time2 - time1));


        CartGroupInstReq cartGroupInstReq = CuccRuleUtil.transGroupCardInstToReq(ruleRequest, busiObject);
        ruleCommonParam.getParams().put("cartGroupInstReq", cartGroupInstReq);
        KiteRuleResponse resp = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);


        long time3 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOnOrderPreview runRule ===============" + (time3 - time2));

        return resp;
    }

    /**
     * 判断附加产品
     * @param cateId
     * @return
     */
    public static boolean isAddRoleProduct(String cateId) {
        DcPublic dcPublic = DcPublicCache.get("20201112001", cateId);
        return Objects.nonNull(dcPublic);
    }

    private static Map getCategoryInfoByInsts(String sceneInstId, List<Map> offerInstFeeList) {
        Map<String, Object> feeCategory = new HashMap<>();
        // 需要校验资费订购数量限制，送规格下的全量信息
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        KiteOfferInst offerInst = RuleUtil.getQuerySceneInstService().getOfferInst(sceneInst.getCustId(), sceneInst.getRootInstId());
        String cateId = OfferCache.get(offerInst.getOfferId()).getCateId();
        if (KiteStringUtils.equalsAny(cateId, DcPublicCache.getCodeb("210728701", "wlwCate").split(","))) {
            return feeCategory;
        }

        List<OfferRelInfo> offerRelInfos = OfferRelCache.get(offerInst.getOfferId()).stream().filter(offerRelInfo ->
            CoreDataOffer.OFF_0005_12.equals(offerRelInfo.getzOfferType()) && KiteStringUtils.equalsAny(offerRelInfo.getRelType(), CoreDataOffer.OFF_0006_100000, CoreDataOffer.OFF_0006_120000)
        ).collect(Collectors.toList());

        offerRelInfos.forEach(offerRelInfo -> {
            Map<String, Object> offerMap = Optional.ofNullable(ProdFeeCache.get(offerRelInfo.getzOfferId()))
                .map(Offer::getOfferMap).orElse(new HashMap<>());
            String jkFeeId = KiteMapUtils.getStrValue(offerMap, "discntCode");
            CategoryOfferDTO categoryOfferDTO = Optional.ofNullable(CategoryOfferCache.get(offerRelInfo.getzOfferId())).orElse(new CategoryOfferDTO());
            if (!feeCategory.containsKey(categoryOfferDTO.getCategoryId())) {
                // 如果是没有记录过的新组别，记录数量限制
                Map<String, Object> limit = new HashMap<>();
                List<String> jkFeeIdList = new ArrayList<>();
                jkFeeIdList.add(jkFeeId);
                limit.put("minNum", categoryOfferDTO.getMinNum());
                limit.put("maxNum", categoryOfferDTO.getMaxNum());
                limit.put("jkFeeIdList", jkFeeIdList);
                feeCategory.put(categoryOfferDTO.getCategoryId(), limit);
            } else {
                // 如果是之前出现过的组别，更新资费编码标识列表即可
                Map limit = (Map) feeCategory.get(categoryOfferDTO.getCategoryId());
                List jkFeeIdList = (List) limit.get("jkFeeIdList");
                jkFeeIdList.add(jkFeeId);
            }
        });
        return feeCategory;
    }

    public static KiteRuleResponse cuccCheckOrderPreViewCommon(String sceneInstId, String custId, RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_ORDER_PREVIEW_COMMON.name());
        setRuleOtherInfo(ruleCommonParam);
        setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }
        long time1 = System.currentTimeMillis();
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        String cateId = "";
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        String rootInstId = sceneInst.getRootInstId();
        KiteOfferInst rootOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(custId, rootInstId);
        String rootOfferId = rootOfferInst.getOfferId();
        //200000106
        Map<String, KiteAttr> map = rootOfferInst.getAttrMap();
        if (KiteMapUtils.isNotEmpty(map)){
            KiteAttr attr = map.get("cateId");
            if (Objects.nonNull(attr)){
                cateId = attr.getValue();
            }
        }

        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);
        ruleCommonParam.getParams().put("isBatchAccept",
            RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "isBatchAccept"));

        //临时处理，融合成员起租时不调规则
        String codea = DcPublicCache.getCodea("202103100001", "RongHeGoodsCateIds");
        String tacheCodes = DcPublicCache.getCodea("202103100001", "RongHeTacheCodes");
        if (!KiteStringUtils.isEmpty(codea) && Arrays.asList(codea.split(",")).contains(cateId)
            && !KiteStringUtils.isEmpty(tacheCodes) && Arrays.asList(tacheCodes.split(",")).contains(tacheCode)) {
            return null;
        }

        //收入归集成员退出   成员信息
        if(serviceOfferId.equals("2022")){
            List<Map<String,Object>> delMemList = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "delGroupUserInfos");
            ruleCommonParam.getParams().put("delMemList", Objects.isNull(delMemList)?new ArrayList<>():delMemList);
        }

        //账户关系
        List acctRelList = new ArrayList();
        if(Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstAcct> offerInstAccts = RuleUtil.getQuerySceneInstService().listOfferInstAccts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstAccts)){
                offerInstAccts.stream().forEach(offerInstAcct ->{
                    Map acctRelMap = KiteMapUtils.beanToMap(offerInstAcct);
                    acctRelList.add(acctRelMap);
                });
            }
        }
        ruleCommonParam.getParams().put("prodInstAcctRels", acctRelList);


        //折扣审批信息
        List kiteOfferInstDiscountList = Lists.newArrayList();
        if (Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstDiscount> offerInstDiscounts = RuleUtil.getQuerySceneInstService().listOfferInstDiscounts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstDiscounts)){
                offerInstDiscounts.stream().forEach(offerInstDiscount ->{
                    Map offerInstDiscountMap = KiteMapUtils.beanToMap(offerInstDiscount);
                    kiteOfferInstDiscountList.add(offerInstDiscountMap);
                });
            }
        }
        ruleCommonParam.getParams().put("offerInstDiscount", kiteOfferInstDiscountList);

        /***
         * 公共信息
         */
        List<KiteAttr> kiteAttrs = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId);
        List attrMapList = new ArrayList();
        kiteAttrs.stream().forEach(commAttr ->{
            attrMapList.add(KiteMapUtils.beanToMap(commAttr));
        });

        ruleCommonParam.getParams().put("commonAttrs", attrMapList);

        /**
         * 资费信息
         */
        List offerInstFeeList = getOfferInstFee(sceneInstId);
        ruleCommonParam.getParams().put("offerInstFee", offerInstFeeList);
        ruleCommonParam.getParams().put("offerFeeSpecMap", getCategoryInfoByInsts(sceneInstId, offerInstFeeList));



        //属性值校验
        Map<String,Object> checkAttrValueMap = new HashMap<>();
        //取产品属性值
        List<KiteProdInst> prodInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(prodInstList)){
            KiteProdInst prodInst = prodInstList.get(0);
            Map<String,KiteAttr> prodInstAttrMap = prodInst.getAttrMap();
            Set<String> keySet = prodInstAttrMap.keySet();
            keySet.stream().forEach(key ->{
                if(KiteStringUtils.equalsAny(key,"2_0000122","2_0000123","2_0000209","2_0000105","2_0000209","2_0000105","2_0000004","2_0000212","2_0000211",LocalKeyConsts.BUSINESS_NUMBER,"2_0000117")){
                    checkAttrValueMap.put(key, prodInstAttrMap.get(key));
                }
            });
        }
        //取公共属性
        List<KiteAttr> checkCommonAttrList = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId).stream().filter(kiteAttr ->
            KiteStringUtils.equalsAny(kiteAttr.getFieldName(),"ORD10012","2_0000004","2_0000212",LocalKeyConsts.BUSINESS_NUMBER)).collect(Collectors.toList());
        checkCommonAttrList.stream().forEach(kiteAttr -> {
            checkAttrValueMap.put(kiteAttr.getFieldName(), kiteAttr);
        });
        ruleCommonParam.getParams().put("checkAttrValueMap", checkAttrValueMap);

        // 批量受理传入把所有信息都传入
        if (KiteStringUtils.equals("T",
            RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "isBatchAccept"))
            && GeneralSwitchUtils.isSwitchOpened("BATCH_ACCEPT_SWITCH")) {
            KiteBatchAcceptDetailMapper kiteBatchAcceptDetailMapper =
                SpringUtil.getBean(KiteBatchAcceptDetailMapper.class);
            String batchId = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "batchId");
            if (KiteStringUtils.isNotEmpty(batchId)) {
                List<KiteBatchAcceptDetail> kiteBatchAcceptDetails =
                    kiteBatchAcceptDetailMapper.select(new KiteBatchAcceptDetail()
                        .setBatchId(Long.valueOf(batchId)));
                if (KiteListUtils.isNotEmpty(kiteBatchAcceptDetails)) {
                    String provinceCode = sceneInst.getProvinceNbr();
                    ProdInst prodInst = busiObject.getProdInstComps().get(0).getProdInsts().get(0);
                    // 包装一个属性作为批量记录的序号
                    KiteAttr firstInstAttr = new KiteAttr();
                    firstInstAttr.setValue(String.valueOf(1));
                    firstInstAttr.setFieldName("batchDetailNum");
                    prodInst.getAttrMap().put(firstInstAttr.getFieldName(), firstInstAttr);
                    for (int i = 1; i < kiteBatchAcceptDetails.size(); i++) {
                        KiteBatchAcceptDetail detail = kiteBatchAcceptDetails.get(i);
                        ProdInst tempProdInst = KiteObjectUtils.clone(prodInst);
                        // 替换属性
                        List<KiteAttr> tempKiteAttrs = JSONObject.parseArray(detail.getAttrJson(), KiteAttr.class);
                        Map<String, Object> attrMap = tempProdInst.getAttrMap();
                        for (KiteAttr tempKiteAttr : tempKiteAttrs) {
                            KiteAttr kiteAttr = (KiteAttr) attrMap.get(tempKiteAttr.getFieldName());
                            if (Objects.isNull(kiteAttr)) {
                                continue;
                            }
                            // 属性转义
                            ProdAttr prodAttr = ProdAttrCache.getByAttrName(tempProdInst.getProdId(), kiteAttr.getFieldName());
                            if (Objects.nonNull(prodAttr) && KiteStringUtils.isNotEmpty(prodAttr.getAttrId())) {
                                String attrValue = AttrValueCache.getAttrValueByAttrValueName(prodAttr.getAttrId(), tempKiteAttr.getValue());
                                if (KiteStringUtils.isNotEmpty(attrValue)) {
                                    kiteAttr.setValue(attrValue);
                                    kiteAttr.setValueDesc(tempKiteAttr.getValue());
                                }
                                else {
                                    kiteAttr.setValue(tempKiteAttr.getValue());
                                }
                            }
                            else {
                                kiteAttr.setValue(tempKiteAttr.getValue());
                            }
                            attrMap.put(tempKiteAttr.getFieldName(), kiteAttr);
                        }
                        // 省市区特殊处理
                        // A端省
                        BatchAcceptUtil.delAddressRule(attrMap, provinceCode, "2_0000220", "2_0000221", "2_0000222",
                            "2_0000209", "2_0000211");
                        // z端省
                        BatchAcceptUtil.delAddressRule(attrMap, provinceCode, "2_0000107", "2_0000109", "2_0000111",
                            "2_0000105", "2_0000117");
                        // mv
                        BatchAcceptUtil.delAddressRuleMVCity(attrMap, provinceCode, "2_0000107", "2_0000109", "2_0000111",
                            "2_0000105");
                        // 包装一个属性作为批量记录的序号
                        KiteAttr kiteAttr = new KiteAttr();
                        kiteAttr.setValue(String.valueOf(i + 1));
                        kiteAttr.setFieldName("batchDetailNum");
                        attrMap.put(kiteAttr.getFieldName(), kiteAttr);
                        tempProdInst.setAttrMap(attrMap);
                        busiObject.getProdInstComps().get(0).getProdInsts().add(tempProdInst);
                    }
                }
            }
        }

        //产品InstSpecRel
        List<InstSpecRel> prodInstSpecRelList = new ArrayList<InstSpecRel>();
        List<KiteProdInst> kiteProdInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(kiteProdInstList)){
            for(KiteProdInst prodInst : kiteProdInstList){
                List<InstSpecRel> prodInstSpecRels = RuleUtil.getInstSpecRelByInst(prodInst, serviceOfferId,custId,sceneInstId);
                prodInstSpecRelList.addAll(prodInstSpecRels);
            }
        }
        //销售品InstSpecRel
        List<InstSpecRel> instSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(prodInstSpecRelList);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        long time2 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOrderPreViewCommon preparedata ===============" + (time2 - time1));

        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);

        long time3 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOrderPreViewCommon runRule ===============" + (time3 - time2));
        return ruleResponse;
    }

    public static KiteRuleResponse cuccCheckOnOrderPreview(String sceneInstId, String custId, RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil.newKiteRuleRequest(sceneInstId, ruleCommonParam, RuleEventType.ET_ORDER_PREVIEW.name());
        setRuleOtherInfo(ruleCommonParam);
        setSceneInstCommonCheckInfo(sceneInstId, ruleCommonParam);
        String serviceOfferId = getServiceOfferId(sceneInstId);
        if (RuleUtil.checkIsClose(ruleRequest)){
            return null;
        }
        long time1 = System.currentTimeMillis();
        InputObject busiObject = RuleUtil.getBusiObjectBySceneInstId(sceneInstId, ruleCommonParam.getCustId());
        String cateId = "";
        KiteSceneInst sceneInst = RuleUtil.getQuerySceneInstService().getSceneInst(sceneInstId);
        String rootInstId = sceneInst.getRootInstId();
        KiteOfferInst rootOfferInst = RuleUtil.getQuerySceneInstService().getOfferInst(custId, rootInstId);

        Map<String, KiteAttr> map = rootOfferInst.getAttrMap();
        if (KiteMapUtils.isNotEmpty(map)){
            KiteAttr attr = map.get("cateId");
            if (Objects.nonNull(attr)){
                cateId = attr.getValue();
            }
        }
        //场景编码
        String tacheCode = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "nodeCode");
        ruleCommonParam.getParams().put("nodeCode", tacheCode);
        //临时处理，融合成员起租时不调规则
        String codea = DcPublicCache.getCodea("202103100001", "RongHeGoodsCateIds");
        String tacheCodes = DcPublicCache.getCodea("202103100001", "RongHeTacheCodes");
        if (!KiteStringUtils.isEmpty(codea) && Arrays.asList(codea.split(",")).contains(cateId)
            && !KiteStringUtils.isEmpty(tacheCodes) && Arrays.asList(tacheCodes.split(",")).contains(tacheCode)) {
            return null;
        }

        /** 总部直签打标处理 */
        String isCenterDirectMark = RuleUtil.getQuerySceneInstService().getExtParameterValue(sceneInstId, "isCenterDirectMark");
        if (KiteStringUtils.isNotEmpty(isCenterDirectMark)) {
            ruleCommonParam.getParams().put("isCenterDirectMark", isCenterDirectMark);
        }

        //账户关系
        List acctRelList = new ArrayList();
        if(Objects.nonNull(rootOfferInst)){
            String accCateId = Optional.ofNullable(rootOfferInst.getAttr("cateId")).map(KiteAttr::getDefaultValue).orElse("");
            if(!isAddRoleProduct(accCateId)){
                List<KiteOfferInstAcct> offerInstAccts = RuleUtil.getQuerySceneInstService().listOfferInstAccts(custId, rootOfferInst.getOfferInstId());
                if (KiteListUtils.isNotEmpty(offerInstAccts)){
                    offerInstAccts.stream().forEach(offerInstAcct ->{
                        Map acctRelMap = KiteMapUtils.beanToMap(offerInstAcct);
                        acctRelList.add(acctRelMap);
                    });
                }
            }
        }
        ruleCommonParam.getParams().put("prodInstAcctRels", acctRelList);


        //折扣审批信息
        List kiteOfferInstDiscountList = Lists.newArrayList();
        if(Objects.nonNull(rootOfferInst)){
            List<KiteOfferInstDiscount> offerInstDiscounts = RuleUtil.getQuerySceneInstService().listOfferInstDiscounts(custId, rootOfferInst.getOfferInstId());
            if (KiteListUtils.isNotEmpty(offerInstDiscounts)){
                offerInstDiscounts.stream().forEach(offerInstDiscount ->{
                    Map offerInstDiscountMap = KiteMapUtils.beanToMap(offerInstDiscount);
                    kiteOfferInstDiscountList.add(offerInstDiscountMap);
                });
            }
        }
        ruleCommonParam.getParams().put("offerInstDiscount", kiteOfferInstDiscountList);

        /**
         * 公共属性
         */
        List<KiteAttr> kiteAttrs = RuleUtil.getQuerySceneInstService().listCommonAttrs(sceneInstId);
        List attrMapList = new ArrayList();
        kiteAttrs.stream().forEach(commAttr ->{
            attrMapList.add(KiteMapUtils.beanToMap(commAttr));
        });
        ruleCommonParam.getParams().put("commonAttrs", attrMapList);


        /**
         * 资费信息
         */
        List offerInstFeeList = getOfferInstFee(sceneInstId);
        ruleCommonParam.getParams().put("offerInstFee", offerInstFeeList);
        ruleCommonParam.getParams().put("offerFeeSpecMap", getCategoryInfoByInsts(sceneInstId, offerInstFeeList));



        //产品InstSpecRel
        List<InstSpecRel> prodInstSpecRelList = new ArrayList<InstSpecRel>();
        List<KiteProdInst> kiteProdInstList = RuleUtil.getQuerySceneInstService().listProdInsts(sceneInstId);
        if(KiteListUtils.isNotEmpty(kiteProdInstList)){
            for(KiteProdInst prodInst : kiteProdInstList){
                List<InstSpecRel> prodInstSpecRels = RuleUtil.getInstSpecRelByInst(prodInst, serviceOfferId,custId,sceneInstId);
                prodInstSpecRelList.addAll(prodInstSpecRels);
            }
        }
        //销售品InstSpecRel
        List<InstSpecRel> instSpecRels = RuleUtil.initInstSpecRelBySceneInstIdLocal(sceneInstId, serviceOfferId, ruleCommonParam,"");
        instSpecRels.addAll(prodInstSpecRelList);
        RuleUtil.setCustOrderIdForRule(instSpecRels, sceneInstId);
        ruleRequest.setRuleInstSpec(RuleInitUtil.newRuleInstSpec(instSpecRels));

        long time2 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOnOrderPreview preparedata ===============" + (time2 - time1));

        KiteRuleResponse resp = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);

        long time3 = System.currentTimeMillis();
        System.out.println("performance analysis: rule - checkOnOrderPreview runRule ===============" + (time3 - time2));

        return resp;
    }

    /**
     * 设置付费关系校验
     * @param ruleCommonParam
     * @return
     */
    public static KiteRuleResponse PIARPayMemberCheck(RuleCommonParam ruleCommonParam) {
        KiteRuleRequest ruleRequest = RuleInitUtil
            .newKiteRuleRequest(ruleCommonParam, CuccRuleEventType.ET_SET_PAY_RELATION_CHECK.name());
        setRuleOtherInfo(ruleCommonParam);

        // 当前规则时机开关已经关闭
        if (RuleUtil.checkIsClose(ruleRequest)) {
            return null;
        }
        InputObject busiObject = new InputObject();
        KiteRuleResponse ruleResponse = RuleTrigger.getRuleEngine(ruleRequest).run(ruleRequest, busiObject);
        return ruleResponse;
    }
}
